package implementations.zuege;

import interfaces.LokInterface;
import interfaces.WagenInterface;
import interfaces.ZugInterface;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public abstract class Zug<W extends WagenInterface> implements ZugInterface<LokInterface, W>
{

	private LokInterface	lok;
	private List<W>			wagons;

	public Zug(LokInterface lok)
	{
		this.lok = lok;
		this.wagons = new ArrayList<W>();
	}

	public String toString()
	{
		String str = "Zug, kann fahren: " + this.hoechstGeschwindigkeit() + " kmh Gesamtmasse: "
				+ this.masse() + " Gesamtkapazitaet: " + this.kapazitaet();
		str += "\n" + this.getClass().getSimpleName() + " hat: ";
		str += "\n\t" + this.lok.toString();

		for (W wagon : this.wagons)
		{
			str += "\n\t" + wagon.toString();
		}

		return str;
	}

	public LokInterface getLok()
	{
		return this.lok;
	}

	@Override
	public double hoechstGeschwindigkeit()
	{
		return this.lok.getHoechstGeschwindigkeit();
	}

	@Override
	public double kapazitaet()
	{

		double gesamtKapazitaet = 0;

		for (WagenInterface w : this.wagons)
		{
			gesamtKapazitaet += w.kapazitaet();
		}
		return gesamtKapazitaet;
	}

	@Override
	public List<W> wagen()
	{
		return this.wagons;
	}

	@Override
	public boolean add(W e)
	{
		return this.wagons.add(e);
	}

	@Override
	public void add(int index, W element)
	{
		this.wagons.add(index, element);

	}

	@Override
	public boolean addAll(Collection<? extends W> c)
	{
		return this.wagons.addAll(c);
	}

	@Override
	public boolean addAll(int index, Collection<? extends W> c)
	{
		return this.wagons.addAll(index, c);
	}

	@Override
	public void clear()
	{
		this.wagons.clear();
	}

	@Override
	public boolean contains(Object o)
	{
		return this.wagons.contains(o);
	}

	@Override
	public boolean containsAll(Collection<?> c)
	{
		return this.wagons.containsAll(c);
	}

	@Override
	public W get(int index)
	{
		return this.wagons.get(index);
	}

	@Override
	public int indexOf(Object o)
	{
		return this.wagons.indexOf(o);
	}

	@Override
	public boolean isEmpty()
	{
		return this.wagons.isEmpty();
	}

	@Override
	public Iterator<W> iterator()
	{
		return this.wagons.iterator();
	}

	@Override
	public int lastIndexOf(Object o)
	{
		return this.lastIndexOf(o);
	}

	@Override
	public ListIterator<W> listIterator()
	{
		return this.wagons.listIterator();
	}

	@Override
	public ListIterator<W> listIterator(int index)
	{
		return this.wagons.listIterator(index);
	}

	@Override
	public boolean remove(Object o)
	{
		return this.wagons.remove(o);
	}

	@Override
	public W remove(int index)
	{
		return this.remove(index);
	}

	@Override
	public boolean removeAll(Collection<?> c)
	{

		return this.wagons.removeAll(c);
	}

	@Override
	public boolean retainAll(Collection<?> c)
	{

		return this.wagons.retainAll(c);
	}

	@Override
	public W set(int index, W element)
	{
		return this.wagons.set(index, element);
	}

	@Override
	public int size()
	{
		return this.wagons.size();
	}

	@Override
	public List<W> subList(int fromIndex, int toIndex)
	{
		return this.wagons.subList(fromIndex, toIndex);
	}

	@Override
	public Object[] toArray()
	{
		return this.wagons.toArray();
	}

	@Override
	public <T> T[] toArray(T[] a)
	{
		return this.toArray(a);
	}

	@Override
	public double masse()
	{
		double masse = 0;

		masse += this.lok.masse();
		for (W wagon : this.wagons)
		{
			masse += wagon.masse();
		}

		return masse;
	}

}
